﻿using FrameworkCore.Models;
using Microsoft.EntityFrameworkCore;

namespace FrameworkCore.Extensions;

public static class AsyncIQueryableExtensions
{
    /// <summary>
    ///  异步将 IQueryable 转换为分页列表。
    /// </summary>
    /// <typeparam name="T">查询结果实体类型</typeparam>
    /// <param name="source">源 IQueryable</param>
    /// <param name="pageIndex">页索引</param>
    /// <param name="pageSize">每页大小</param>
    /// <param name="getOnlyTotalCount">一个值，指示是否仅加载记录总数。如果设置为 "true"，则不会从数据库加载数据。</param>
    /// <param name="cancellationToken"></param>
    /// <returns>表示异步操作的任务，返回泛型IPagedList对象</returns>
    public static async Task<IPagedList<T>> ToPagedListAsync<T>(this IQueryable<T> source, int pageIndex, int pageSize, bool getOnlyTotalCount = false, CancellationToken cancellationToken = default)
    {
        if (source == null)
            return new PagedList<T>(new List<T>(), pageIndex, pageSize);

        // 最小允许的页大小为 1
        pageSize = Math.Max(pageSize, 1);

        var count = await source.CountAsync();

        var data = new List<T>();

        // 如果不仅获取总数，则从数据库加载数据
        if (!getOnlyTotalCount)
            data.AddRange(await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(cancellationToken));

        return new PagedList<T>(data, pageIndex, pageSize, count);
    }

    /// <summary>
    /// 将 IQueryable 转换为分页列表。
    /// </summary>
    /// <typeparam name="T">查询结果实体类型</typeparam>
    /// <param name="source">源 IQueryable</param>
    /// <param name="pageIndex">页索引</param>
    /// <param name="pageSize">每页大小</param>
    /// <param name="getOnlyTotalCount">一个值，指示是否仅加载记录总数。如果设置为 "true"，则不会从数据库加载数据。</param>
    /// <returns>返回泛型IPagedList对象</returns>
    public static IPagedList<T> ToPagedList<T>(this IQueryable<T> source, int pageIndex, int pageSize, bool getOnlyTotalCount = false)
    {
        if (source == null)
            return new PagedList<T>(new List<T>(), pageIndex, pageSize);

        // 最小允许的页大小为 1
        pageSize = Math.Max(pageSize, 1);

        var count = source.Count();

        var data = new List<T>();

        // 如果不仅获取总数，则从数据库加载数据
        if (!getOnlyTotalCount)
            data.AddRange(source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList());

        return new PagedList<T>(data, pageIndex, pageSize, count);
    }
}
